<template>
  <div class="bulletin_box" @click="closeVisible">
    <div :class="['detail_item', 'site_box', { not_site: typeList.length == 0 }]">
      <div class="flex justify-between items-center">
        <div class="manage_tit" style="align-items: anchor-center">
          <div class="line"></div>
          <span class="ml-2">场地看板</span>
          <div class="motion_type">
            <div
              :class="['type_item', { active: siteParams.type == item.dictLabel }]"
              v-for="item in typeList"
              :key="item.dictLabel"
              @click="changeType(item.dictLabel)"
            >
              {{ item.dictValue }}
            </div>
          </div>
        </div>
        <div class="handle_site">
          <div class="refresh" @click="refreshBulletin">
            <img :src="typeList.length == 0 ? disRefreshImg : refreshIconImg" alt="" />
            <span>刷新</span>
          </div>
          <div
            class="edit"
            v-hasPermi="['sys:site:btn_update']"
            v-show="isInit"
            @click="handleAddSite"
          >
            <img :src="typeList.length == 0 ? disEditImg : editIconImg" alt="" />
            <span>编辑</span>
          </div>
          <div
            class="edit"
            v-hasPermi="['sys:stadium:btn_set_price']"
            v-show="isInit"
            @click="handleSetSite"
          >
            <img :src="typeList.length == 0 ? disEditImg : editIconImg" alt="" />
            <span>价格模版</span>
          </div>
        </div>
      </div>
      <div class="site_cont">
        <template v-if="typeList.length > 0">
          <div class="flex justify-between mb-3">
            <div class="flex items-center">
              <div class="date_box align_center">
                <div class="today date_item" @click="changeToday">
                  <img :src="todayImg" alt="" />
                  <span>返回今日</span>
                </div>
                <div class="date_list align_center">
                  <div
                    class="w-5 h-12 bg-color-F1F2F3 rounded flex items-center justify-center mr-3 cursor-pointer"
                    @click="handlePrevWeek"
                  >
                    <img :src="dateLeftImg" />
                  </div>
                  <div
                    :class="['date_item', { active: siteParams.date == item.formatDates }]"
                    v-for="(item, index) in weekList"
                    :key="index"
                    @click="changeDate(item.formatDates)"
                  >
                    <p class="today_logo" v-if="siteParams.date == todayDate">
                      <img :src="todayLogoImg" class="block" />
                    </p>
                    <p>{{ item.date }}</p>
                    <span>{{ item.weekDay }}</span>
                  </div>
                  <div
                    class="w-5 h-12 bg-color-F1F2F3 rounded flex items-center justify-center mr-3 cursor-pointer"
                    @click="handleNextWeek"
                  >
                    <img :src="dateRightImg" />
                  </div>
                </div>
                <div class="date_item today date_sel">
                  <img :src="todayImg" alt="" />
                  <span>选择日期</span>
                  <el-date-picker
                    @change="handleChangeDate"
                    v-model="siteParams.date"
                    type="date"
                    value-format="yyyy/MM/dd"
                    style="width: 50px; height: 48px"
                  >
                  </el-date-picker>
                </div>
              </div>
              <!-- <div class="search_boxs flex">
                <div class="ml-4">
                  <p>查询订单</p>
                  <div class="flex">
                    <el-input
                      placeholder="请输入订单号、手机号"
                      v-model="orderPhone"
                      clearable
                    ></el-input>
                    <el-popover
                      placement="bottom-end"
                      width="440"
                      trigger="manual"
                      v-model="orderVisible"
                      popper-class="order_popper"
                      ref="orderPopper"
                    >
                      <el-table :data="orderList">
                        <el-table-column
                          label="用户信息"
                          prop="nickName"
                          width="80"
                        ></el-table-column>
                        <el-table-column
                          label="手机号码"
                          prop="orderPhone"
                          width="110"
                        ></el-table-column>
                        <el-table-column label="订场信息">
                          <template slot-scope="{ row }">
                            <div
                              v-for="(item, index) in row.detailVoList"
                              :key="index"
                            >
                              <span>{{
                                item.orderType == 1
                                  ? `散客${item.siteName}`
                                  : item.siteName
                              }}</span>
                              <span class="ml-3">{{
                                item.orderType == 1 ? "不限时段" : item.times
                              }}</span>
                            </div>
                          </template>
                        </el-table-column>
                        <el-table-column width="60" label="操作">
                          <template slot-scope="{ row }">
                            <el-button
                              type="text"
                              @click="goOrderDetail(row.orderId)"
                              >查看</el-button
                            >
                          </template>
                        </el-table-column>
                      </el-table>
                      <el-button
                        slot="reference"
                        class="sure_btn"
                        @click="searchOrder"
                        >查询</el-button
                      >
                    </el-popover>
                  </div>
                </div>
                <div class="ml-4">
                  <p>核销订单</p>
                  <div class="flex">
                    <el-input
                      v-model="inputCode"
                      placeholder="请输入6位核销码"
                      clearable
                    ></el-input>
                    <el-popover
                      placement="bottom-end"
                      width="725"
                      trigger="manual"
                      v-model="writeOffVisible"
                      popper-class="order_popper"
                    >
                      <el-table :data="writeOffList">
                        <el-table-column
                          label="订单编号"
                          prop="orderNo"
                          width="180"
                        ></el-table-column>
                        <el-table-column
                          label="用户信息"
                          prop="nickName"
                          width="80"
                        ></el-table-column>
                        <el-table-column
                          label="手机号码"
                          width="120"
                          prop="orderPhone"
                        ></el-table-column>
                        <el-table-column label="订场信息">
                          <template slot-scope="{ row }">
                            <div>
                              <span>{{
                                row.orderType == 2
                                  ? `散客${row.siteName}`
                                  : row.siteName
                              }}</span>
                              <span class="ml-3">{{
                                row.orderType == 2 ? "不限时段" : row.times
                              }}</span>
                            </div>
                          </template>
                        </el-table-column>
                        <el-table-column
                          label="下单时间"
                          prop="formatDate"
                        ></el-table-column>
                      </el-table>
                      <div class="flex justify-end my-2.5 write_btn">
                        <el-button type="primary" @click="handleWriteOff"
                          >确认核销</el-button
                        >
                        <el-button @click="writeOffVisible = false"
                          >取消</el-button
                        >
                      </div>
                      <el-button
                        slot="reference"
                        class="sure_btn"
                        @click="getWriteOrder"
                        >确定</el-button
                      >
                    </el-popover>
                  </div>
                </div>
              </div> -->
            </div>
            <div class="site_num">
              <p>预定场地：{{ siteData.reserveCount }}</p>
              <p class="mt-1.5">空闲场地：{{ siteData.reserveNoCount }}</p>
            </div>
          </div>
          <div class="select_box" v-loading="siteLoading">
            <div class="select_table">
              <div class="flex relative">
                <div class="table-wrapper">
                  <div
                    class="table table-container"
                    ref="tableContainer"
                    @mousedown="startSelection"
                    @mousemove="updateSelection"
                    @mouseup="endUpSelection"
                    @mouseleave="endSelection"
                  >
                    <table border="1">
                      <thead>
                        <tr>
                          <th>
                            <el-select
                              filterable
                              placeholder="请选择"
                              v-model="templateId"
                              ref="tempSelect"
                              @visible-change="tempVisibleChange"
                            >
                              <el-option
                                :label="item.templateName"
                                :value="item.id"
                                v-for="item in templateList"
                                :key="item.id"
                                @click="changeTemplate"
                              ></el-option>
                            </el-select>
                          </th>
                          <th v-for="t in siteData.reserveList" :key="t.time">
                            <p class="time">{{ t.time }}</p>
                          </th>
                          <th>
                            <p style="margin-left: -34px">{{ lastTime }}</p>
                          </th>
                        </tr>
                        <tr>
                          <th>当前预定数</th>
                          <th
                            v-for="t in siteData.reserveList"
                            :key="'c' + t.time"
                            class="reserve_num"
                          >
                            <p>{{ t.countAll }}</p>
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        <template v-if="fitList.length > 0">
                          <tr v-for="fit in fitList" :key="fit.siteId + 'site'">
                            <td>
                              <p class="leading-5">
                                {{ `散客${fit.siteName}` }}
                              </p>
                              <el-switch
                                v-model="fit.showFlag"
                                :active-value="'0'"
                                :inactive-value="'1'"
                                active-color="#2A82E4"
                                inactive-color="#E5E5E5"
                                :width="54"
                                @change="(val) => changeShowFit(val, fit)"
                              >
                              </el-switch>
                            </td>
                            <td
                              v-if="fit.showFlag == 0"
                              :colspan="
                                siteData && siteData.reserveList && siteData.reserveList.length
                              "
                              :class="{
                                expire: fit.disabled,
                                selected: bulletinObj.siteId == fit.siteId,
                                free: fit.orderList.length == 0,
                              }"
                              @click="
                                fit.orderList.length == 0 && !fit.disabled && handleClickFit(fit)
                              "
                            >
                              <div class="td_cell" v-if="fit.orderList.length == 0">
                                <el-popover
                                  placement="bottom"
                                  width="200"
                                  trigger="hover"
                                  popper-class="builletin_popper"
                                >
                                  <div class="popover_box">
                                    <div class="popover_tit">
                                      <span>{{ fit.disabled ? '已过时' : '空闲中' }}</span>
                                    </div>
                                    <div class="popover_cont">
                                      <p><span>散客场</span><span class="ml-2">不限时段</span></p>
                                    </div>
                                  </div>
                                  <template v-slot:reference>
                                    <div>
                                      <p class="text-custom-blue">￥{{ fit.price }}</p>
                                    </div>
                                  </template>
                                </el-popover>
                              </div>
                              <div class="td_cell" v-else>
                                <div class="w-full h-full flex">
                                  <div
                                    :class="[
                                      'fit_item',
                                      {
                                        active: bulletinObj.orderId == o.orderId,
                                      },
                                    ]"
                                    v-for="o in fit.orderList"
                                    :key="o.orderId"
                                    @click="handleClickFitItem(fit, o)"
                                  >
                                    <el-popover
                                      placement="right"
                                      width="200"
                                      trigger="hover"
                                      popper-class="builletin_popper"
                                    >
                                      <div class="popover_box">
                                        <div class="popover_tit">
                                          <span>散客订场</span>
                                        </div>
                                        <div class="popover_cont">
                                          <p>
                                            <span>{{ o.nickName }}</span
                                            ><span class="ml-2">{{ o.orderPhone }}</span>
                                          </p>
                                        </div>
                                      </div>
                                      <template v-slot:reference>
                                        <div>
                                          <div>
                                            <p class="nick_name">
                                              {{ o.nickName }}
                                            </p>
                                            <div class="phone">
                                              <p>手机号</p>
                                              <p>
                                                {{ o.orderPhone }}
                                              </p>
                                            </div>
                                          </div>
                                        </div>
                                      </template>
                                    </el-popover>
                                  </div>
                                </div>
                              </div>
                            </td>
                          </tr>
                        </template>
                        <tr v-for="(item, rowIndex) in siteData.siteList" :key="item.id">
                          <td>
                            <p>
                              {{ item.siteName }}
                            </p>
                          </td>
                          <template v-for="(t, cellIndex) in siteData.reserveList">
                            <td
                              v-if="shouldRender(item.id, t.time)"
                              :key="t.time"
                              :colspan="colSpan(item.id, t.time)"
                              :class="[
                                cellCls(item.id, t),
                                {
                                  selected:
                                    isSelected(rowIndex, cellIndex) ||
                                    (selectedCell &&
                                      selectedCell.rowIndex === rowIndex &&
                                      selectedCell.cellIndex === cellIndex),
                                },
                              ]"
                              :data-row="rowIndex"
                              :data-col="cellIndex"
                              class="tdSelection"
                              @click="handleClick(item, t, rowIndex, cellIndex)"
                            >
                              <div class="td_cell">
                                <div v-if="getCell(item.id, t.time)">
                                  <!-- 已预约 -->
                                  <template
                                    v-if="
                                      getCell(item.id, t.time).orderType == 0 ||
                                      getCell(item.id, t.time).orderType == 1
                                    "
                                  >
                                    <div>
                                      <p>
                                        {{ getCell(item.id, t.time).nickName }}
                                      </p>
                                      <div class="phone">
                                        <p>手机号</p>
                                        <p>
                                          {{ getCell(item.id, t.time).orderPhone }}
                                        </p>
                                      </div>
                                    </div>
                                  </template>
                                  <!-- 已锁定 -->
                                  <template v-else-if="getCell(item.id, t.time).orderType == 2">
                                    <div class="lock-text">
                                      <img :src="lockIconImg" />
                                    </div>
                                  </template>
                                </div>
                                <template v-else>
                                  {{
                                    getMap(item.id, t).price ? `￥${getMap(item.id, t).price}` : ''
                                  }}
                                </template>
                              </div>
                            </td>
                          </template>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                </div>
              </div>
            </div>
            <div class="select_block">
              <div class="block_item">
                <span class="block"></span>
                <p>空闲中</p>
              </div>
              <div class="block_item">
                <span class="block bg-color-E5E5E5"></span>
                <p>已过时</p>
              </div>
              <div class="block_item">
                <span class="block bg-color-43CF7C"></span>
                <p>待确认</p>
              </div>
              <div class="block_item">
                <span class="block bg-color-FF8D1A"></span>
                <p>散客订场</p>
              </div>
              <div class="block_item">
                <span class="block bg-custom-blue"></span>
                <p>小程序订场</p>
              </div>
              <div class="block_item">
                <span class="block bg-custom-main"></span>
                <p>场地锁定</p>
              </div>
            </div>
          </div>
        </template>
        <template v-if="isInit && typeList.length == 0">
          <div class="not_set">
            <img :src="notContImg" alt="" />
            <div>
              <p class="p1">尚未设置场地看板</p>
              <p class="p2" @click="handleAddSite">去设置》</p>
            </div>
          </div>
        </template>
      </div>
    </div>
    <edit-site
      :show="showEditSite"
      :stadiumId="stadiumId"
      :stadiumType="stadiumData.stadiumType"
      :types="siteTypeList"
      v-model:show-add-type="showAddType"
      v-bind:data-status="dataStatus"
      @close="closeSiteDialog"
      @addType="showEditSite = true"
      ref="editSiteRef"
    />
    <bulletin-detail
      :drawer="drawerVisible"
      v-model:data="bulletinObj"
      v-model:dataList="bulletinList"
      :stadiumData="stadiumData"
      :siteData="bulletinData"
      @close="closeBulletin"
      @success="refreshBulletin"
    ></bulletin-detail>
    <!--设置弹框 -->
    <el-dialog
      v-model="showSetPrice"
      width="75%"
      append-to-body
      :close-on-click-modal="false"
      :show-close="false"
      custom-class="set_price_dialog"
      v-dialog-drag
    >
      <template #title>
        <div class="flex justify-between items-center">
          <div class="manage_tit">
            <div class="line"></div>
            <p>价格模版设置</p>
          </div>
          <div class="dialog_close" @click="closeSetPrice">
            <img :src="closeIconImg" />
          </div>
        </div>
      </template>
      <session-detail ref="sessionDetailRef" @cancel="closeSetPriceTemp"></session-detail>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
// 图片资源引入
import refreshIconImg from '@/assets/images/icon/refresh_icon.png'
import disRefreshImg from '@/assets/images/icon/dis_refresh.png'
import editIconImg from '@/assets/images/icon/edit_icon.png'
import disEditImg from '@/assets/images/icon/dis_edit.png'
import todayImg from '@/assets/images/icon/today.png'
import todayLogoImg from '@/assets/images/icon/today_logo.png'
import dateLeftImg from '@/assets/images/icon/date_left.png'
import dateRightImg from '@/assets/images/icon/date_right.png'
import lockIconImg from '@/assets/images/icon/lock_icon.png'
import notContImg from '@/assets/images/icon/not_cont.png'
import closeIconImg from '@/assets/images/icon/close_icon.png'

const timeToMinutes = (t: string) => {
  const parts = t.split(':').map(Number)
  const h = parts[0] || 0
  const m = parts[1] || 0
  return h * 60 + m
}

import { ref, reactive, computed, onMounted, nextTick, watch } from 'vue'
import { debounce } from 'lodash'
import dayjs from 'dayjs'
import { getWeekDates } from '@/utils/index'
import { getBulletinListByStadiumId, getTemplateList, applyTemplate } from '@/api/stadium/stadium'
import {
  getBulletinListByDateType,
  selectSiteListBySiteType,
  getOrderListByStadiumIdAndSite,
  updateShowSite,
} from '@/api/site/site'
import { getOrderBasicInfo, getOrderDetailByCode, writeCode } from '@/api/order/order'
import bulletinDetail from './bulletinDetail.vue'
import EditSite from './editSite.vue'
import SessionDetail from './sessionDetail.vue'
import { useStore } from 'vuex'

// 定义组件名称和属性
defineOptions({
  name: 'HourlyTable',
})

// 定义props
interface Props {
  show?: boolean
  stadiumId?: number | string | null
  stadiumData?: any
  orderDate?: string | null
  orderStadiumType?: string | number | null
}

const props = withDefaults(defineProps<Props>(), {
  show: false,
  stadiumId: null,
  stadiumData: () => ({}),
  orderDate: null,
  orderStadiumType: null,
})

// 定义emit事件
const emit = defineEmits<{
  (e: 'close'): void
}>()

// 引入store
const store = useStore()

// 框选数据开始
const selectedCells = ref<string[]>([])
const isSelecting = ref(false)
const selectionStart = reactive({ row: null as number | null, col: null as number | null })
const selectionEnd = reactive({ row: null as number | null, col: null as number | null })

// 场地看板数据
const siteData = ref<any>({})
const weekList = ref<any[]>([])
const todayDate = ref<string>('')
const typeList = ref<any[]>([])
const siteParams = reactive({
  date: null as string | null,
  stadiumId: null as string | number | null,
  type: null as string | number | null,
})
const activeIndex = ref(0)
const templateList = ref<any[]>([])
const templateId = ref<string | number | null>(null)
const templateIdVal = ref<string | number | null>(null)
const siteTypeList = ref<any[]>([])
const lastTime = ref<string | null>(null)
const siteLoading = ref(false)
const bookedList = ref<any[]>([])
const drawerVisible = ref(false)
const bulletinObj = ref<any>({})
const bulletinData = ref<any>({})
const orderPhone = ref('')
const orderList = ref<any[]>([])
const orderVisible = ref(false)
const inputCode = ref('')
const writeOffVisible = ref(false)
const writeOffList = ref<any[]>([])
const showSetPrice = ref(false)
const showEditSite = ref(false)
const showAddType = ref(false)
const dataStatus = ref('')
const selectedCell = ref<{ rowIndex: number; cellIndex: number } | null>(null)
const value = ref(false)
const fitList = ref<any[]>([])
const isInit = ref(false)
const bulletinList = ref<any[]>([])

// refs引用
const tableContainer = ref<HTMLElement | null>(null)
const tempSelect = ref<any>(null)
const editSiteRef = ref<InstanceType<typeof EditSite> | null>(null)
const sessionDetailRef = ref<InstanceType<typeof SessionDetail> | null>(null)

// 核心1: 选择框样式计算（考虑滚动位置）
const selectionBoxStyle = computed(() => {
  if (!isSelecting.value || selectionStart.row === null || selectionEnd.row === null) {
    return { display: 'none' }
  }

  const tableContainerEl = tableContainer.value
  if (!tableContainerEl) return { display: 'none' }

  const tableRect = tableContainerEl.getBoundingClientRect()
  const scrollLeft = tableContainerEl.scrollLeft
  const scrollTop = tableContainerEl.scrollTop

  // 这里需要根据实际DOM结构获取单元格元素
  // 由于在setup中无法直接访问DOM元素，需要在事件处理中处理

  return {
    display: 'block',
  }
})

const selectionRange = computed(() => {
  if (!isSelecting.value || selectionStart.row === null || selectionEnd.row === null) {
    return '无'
  }

  const startRow = Math.min(selectionStart.row, selectionEnd.row)
  const endRow = Math.max(selectionStart.row, selectionEnd.row)
  const startCol = Math.min(selectionStart.col!, selectionEnd.col!)
  const endCol = Math.max(selectionStart.col!, selectionEnd.col!)

  return `行 ${startRow + 1}-${endRow + 1}, 列 ${startCol + 1}-${endCol + 1}`
})

// 监听drawerVisible变化
watch(drawerVisible, (val) => {
  if (!val) {
    clearSelection()
  }
})

// 框选数据相关方法
const startSelection = (event: MouseEvent) => {
  // 确保点击的是单元格
  const target = event.target as HTMLElement
  const cell = target.closest('.tdSelection')
  if (!cell) return
  const row = parseInt(cell.getAttribute('data-row') || '0')
  const col = parseInt(cell.getAttribute('data-col') || '0')
  clearSelection()
  selectionStart.row = row
  selectionStart.col = col
  selectionEnd.row = row
  selectionEnd.col = col
  isSelecting.value = true
  updateSelectedCells()
  bindGlobalEvents()
  event.preventDefault()
}

// 绑定全局事件
const bindGlobalEvents = () => {
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', endSelection)
}

// 鼠标移动处理（包含自动滚动）
const handleMouseMove = (event: MouseEvent) => {
  if (!isSelecting.value) return

  // 获取当前鼠标位置的单元格
  const element = document.elementFromPoint(event.clientX, event.clientY) as HTMLElement
  if (element && element.tagName === 'TD') {
    const row = parseInt(element.getAttribute('data-row') || '0')
    const col = parseInt(element.getAttribute('data-col') || '0')
    selectionEnd.row = row
    selectionEnd.col = col
    updateSelectedCells()
  }

  // 自动滚动逻辑
  handleAutoScroll(event)
}

// 自动滚动处理
const handleAutoScroll = (event: MouseEvent) => {
  const container = tableContainer.value
  if (!container) return

  const rect = container.getBoundingClientRect()
  const scrollMargin = 30 // 距离边缘多少像素开始滚动

  // 水平滚动
  if (event.clientX < rect.left + scrollMargin) {
    container.scrollLeft -= 10
  } else if (event.clientX > rect.right - scrollMargin) {
    container.scrollLeft += 10
  }

  // 垂直滚动
  if (event.clientY < rect.top + scrollMargin) {
    container.scrollTop -= 10
  } else if (event.clientY > rect.bottom - scrollMargin) {
    container.scrollTop += 10
  }
}

// 辅助方法：获取单元格元素
const getCellElement = (row: number, col: number) => {
  const selector = `td[data-row="${row}"][data-col="${col}"]`
  return tableContainer.value?.querySelector(selector)
}

const updateSelection = (event: MouseEvent) => {
  if (!isSelecting.value) return

  const target = event.target as HTMLElement
  const cell = target.closest('td')
  if (!cell) return

  const row = parseInt(cell.getAttribute('data-row') || '0')
  const col = parseInt(cell.getAttribute('data-col') || '0')

  selectionEnd.row = row
  selectionEnd.col = col
  updateSelectedCells()
}

const endSelection = () => {
  isSelecting.value = false
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', endSelection)
}

const endUpSelection = () => {
  isSelecting.value = false
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', endSelection)
  confirmSelection()
}

// 确认选择
const confirmSelection = () => {
  const siteDataValue = siteData.value // siteList场地类型的列表就是行的数据，reserveList时间的列表就是几列，reserveList.mapList是列的数据
  const selectedCellsValue = selectedCells.value // 选中的数据'行-列'比如0-1，是第一行第二列
  const bulletinListValue: any[] = [] // 选中的数据整合

  selectedCellsValue.forEach((item) => {
    const parts = item.split('-')
    const lineIndex = parts[1] !== undefined ? parseInt(parts[1]) : 0 // 列
    const rowIndex = parts[0] !== undefined ? parseInt(parts[0]) : 0 // 行
    const selectedData = siteDataValue.reserveList[lineIndex].mapList[rowIndex]
    const lineData = siteDataValue.reserveList[lineIndex] // 选中列的数据

    if (!selectedData.disabled || (selectedData.disabled && selectedData.orderType == '2')) {
      // 去除不可编辑的场次已过期的
      selectedData.time = lineData.timeRange
      selectedData.bulletinDate = lineData.bulletinDate
      bulletinListValue.push(selectedData)
    }
  })

  if (bulletinListValue.length == 1) {
    bulletinObj.value = bulletinListValue[0]
  } else {
    bulletinList.value = bulletinListValue
  }

  if (bulletinList.value.length > 0) {
    drawerVisible.value = true
  }
}

const clearSelection = () => {
  selectedCells.value = []
  selectionStart.row = null
  selectionStart.col = null
  selectionEnd.row = null
  selectionEnd.col = null
}

const updateSelectedCells = () => {
  if (
    selectionStart.row === null ||
    selectionEnd.row === null ||
    selectionStart.col === null ||
    selectionEnd.col === null
  )
    return

  const startRow = Math.min(selectionStart.row, selectionEnd.row)
  const endRow = Math.max(selectionStart.row, selectionEnd.row)
  const startCol = Math.min(selectionStart.col, selectionEnd.col)
  const endCol = Math.max(selectionStart.col, selectionEnd.col)

  const currentSelection: string[] = []
  for (let row = startRow; row <= endRow; row++) {
    for (let col = startCol; col <= endCol; col++) {
      currentSelection.push(`${row}-${col}`)
    }
  }
  selectedCells.value = currentSelection
}

const toggleCellSelection = (row: number, col: number) => {
  const cellKey = `${row}-${col}`
  const index = selectedCells.value.indexOf(cellKey)

  if (index > -1) {
    selectedCells.value.splice(index, 1)
  } else {
    selectedCells.value.push(cellKey)
  }
}

const isSelected = (row: number, col: number) => {
  return selectedCells.value.includes(`${row}-${col}`)
}

const isHighlighted = (row: number, col: number) => {
  if (!isSelecting.value || selectionStart.row === null || selectionEnd.row === null) {
    return false
  }

  const startRow = Math.min(selectionStart.row, selectionEnd.row)
  const endRow = Math.max(selectionStart.row, selectionEnd.row)
  const startCol = Math.min(selectionStart.col!, selectionEnd.col!)
  const endCol = Math.max(selectionStart.col!, selectionEnd.col!)

  return row >= startRow && row <= endRow && col >= startCol && col <= endCol
}

// 初始化数据
const initData = (data: any[]) => {
  drawerVisible.value = false
  todayDate.value = props.orderDate || dayjs(new Date()).format('YYYY/MM/DD')
  typeList.value = data
  siteParams.stadiumId = props.stadiumId
  siteParams.date = props.orderDate || todayDate.value
  weekList.value = getWeekDates(props.orderDate || todayDate.value)
  getFit()
  nextTick(() => {
    siteParams.type = props.orderStadiumType || typeList.value?.[0]?.dictLabel
    if (siteParams.type) {
      getReserve()
      getBulletin()
    }
    getTemplate()
  })
  getSiteType()
}

// 清空数据
const resetData = () => {
  typeList.value = []
  siteData.value = {}
  fitList.value = []
}

// 获取场地看板信息
const getBulletin = async () => {
  if (!siteLoading.value) {
    siteLoading.value = true
    try {
      const { data } = await getBulletinListByStadiumId(siteParams)
      isInit.value = true
      siteData.value = data
      templateId.value = data.templateId
      lastTime.value =
        siteData.value.reserveList[siteData.value.reserveList.length - 1].timeRange.split('-')[1]
      const newArray = siteData.value.reserveList.map((obj: any) => {
        return { time: obj.time }
      })
      bulletinData.value = {
        siteList: siteData.value.siteList,
        reserveList: newArray,
      }
    } finally {
      siteLoading.value = false
    }
  } else {
    // 系统逻辑一秒内重复点击会有重复点击提示，必须一秒之后去掉加载icon
    setTimeout(() => {
      siteLoading.value = false
    }, 1000)
  }
}

// 获取散客场地信息
const getFit = async () => {
  const params = {
    userId: store.state.user.id,
    ...siteParams,
  }
  const { data } = await getOrderListByStadiumIdAndSite(params)
  fitList.value = data
}

// 获取已经被预约的场次列表
const getReserve = async () => {
  const params = {
    date: siteParams.date,
    stadiumId: siteParams.stadiumId,
    siteType: siteParams.type,
  }
  const { data } = await getBulletinListByDateType(params)
  bookedList.value = data
}

// 查询订单列表
const searchOrder = async () => {
  if (orderPhone.value != '') {
    const { data } = await getOrderBasicInfo({
      stadiumId: siteParams.stadiumId,
      orderPhone: orderPhone.value,
      orderDate: siteParams.date,
    })
    orderList.value = data
    if (orderList.value.length > 0) {
      orderVisible.value = true
    }
  } else {
    orderList.value = []
    orderVisible.value = false
  }
}

// 跳转到订单详情
const goOrderDetail = (id: string) => {
  // 这里需要使用vue-router，但在setup中需要通过useRouter
  // 由于原始代码中使用了this.$router，这里保持相似逻辑
  window.location.hash = `#/order/detail?id=${id}`
}

// 根据核销码获取核销订单详情
const getWriteOrder = async () => {
  if (inputCode.value != '') {
    const { data } = await getOrderDetailByCode({
      verificationCode: inputCode.value,
    })
    writeOffList.value = [data]
    if (writeOffList.value.length > 0) {
      writeOffVisible.value = true
    }
  } else {
    writeOffList.value = []
    writeOffVisible.value = false
  }
}

// 确认核销
const handleWriteOff = debounce(
  async () => {
    const params = {
      userId: store.state.user.id,
      inputCode: inputCode.value,
      deptId: store.state.user.deptId,
      userName: store.state.user.name,
    }
    const res = await writeCode(params)
    // 这里需要访问this.$message，但在setup中需要其他方式
    alert(res.msg) // 临时替代
    inputCode.value = ''
    writeOffVisible.value = false
  },
  1000,
  {
    leading: true,
    trailing: false,
  },
)

// 刷新
const refreshBulletin = () => {
  getBulletin()
  getFit()
  getReserve()
}

// 点击弹窗关闭按钮关闭价格模版设置弹窗
const closeSetPrice = () => {
  if (sessionDetailRef.value) {
    sessionDetailRef.value.handleCancel()
  }
}

// 关闭价格模版设置弹窗
const closeSetPriceTemp = () => {
  showSetPrice.value = false
  getTemplate()
}

// 编辑场地
const handleEditSite = () => {
  showEditSite.value = true
}

// 关闭编辑场地弹窗
const closeSiteDialog = (val?: any) => {
  showEditSite.value = false
  getSiteType()
}

// 返回今日
const changeToday = () => {
  siteParams.date = dayjs(new Date()).format('YYYY/MM/DD')
  weekList.value = getWeekDates()
  getBulletin()
  getFit()
  getReserve()
}

// 切换日期
const changeDate = (val: string) => {
  siteParams.date = val
  getBulletin()
  getFit()
  getReserve()
}

// 日历选择日期
const handleChangeDate = () => {
  const d = new Date(siteParams.date as string) // 如果当期日期是7号或者小于7号
  d.setDate(d.getDate())
  weekList.value = getWeekDates(d)
  getBulletin()
  getFit()
  getReserve()
}

// 上个星期
const handlePrevWeek = () => {
  const d = new Date(weekList.value[0].formatDates) // 如果当期日期是7号或者小于7号
  d.setDate(d.getDate() - 7)
  weekList.value = getWeekDates(d)
  siteParams.date = weekList.value[0].formatDates
  getBulletin()
  getFit()
  getReserve()
}

// 下个星期
const handleNextWeek = () => {
  const d = new Date(weekList.value[6].formatDates) // 如果当期日期是7号或者小于7号
  d.setDate(d.getDate() + 1)
  weekList.value = getWeekDates(d)
  siteParams.date = weekList.value[0].formatDates
  getBulletin()
  getFit()
  getReserve()
}

// 获取价格
const getMap = (id: string, data: any) => {
  return data.mapList.find((item: any) => item.siteId == id)
}

// 获取指定格业务对象
const getCell = (siteId: string, t: string) => {
  return bookedList.value.find(
    (c: any) =>
      c.siteId === siteId &&
      timeToMinutes(t) >= timeToMinutes(c.startTime) &&
      timeToMinutes(t) < timeToMinutes(c.endTime),
  )
}

// 是否渲染（首格才渲染）
const shouldRender = (siteId: string, t: string) => {
  const cell = bookedList.value.find((c: any) => c.siteId === siteId && c.startTime === t)
  if (cell) return true
  return !getCell(siteId, t)
}

// 计算 colspan（跨多少 1 小时格）
const colSpan = (siteId: string, t: string) => {
  const cell = bookedList.value.find((c: any) => c.siteId === siteId && c.startTime === t)
  if (!cell) return 1
  return (timeToMinutes(cell.endTime) - timeToMinutes(cell.startTime)) / 60
}

// 样式类名
const cellCls = (siteId: string, t: any) => {
  const cell = getCell(siteId, t.time)
  if (cell && cell.orderType == 2) return 'lock'
  if (cell && (cell.orderType == 0 || cell.orderType == 1)) {
    if (cell.orderFlag == 8) {
      return 'confirmed'
    } else {
      return 'booked'
    }
  }
  if (getMap(siteId, t).disabled) return 'expire'
  return 'free'
}

// 选择场地类型
const changeType = (val: string) => {
  siteParams.type = val
  getBulletin()
  getFit()
  getTemplate()
  getReserve()
}

// 点击未预定的散客
const handleClickFit = (item: any) => {
  clearSelection() // 点击就清除掉框选的数据
  bulletinObj.value = item
  bulletinObj.value.isIndependence = 1
  bulletinObj.value.bulletinDate = siteParams.date
  bulletinObj.value.time = siteData.value.reserveList[0].timeRange
  drawerVisible.value = true
}

// 点击已预定的散客
const handleClickFitItem = (item: any, subItem: any) => {
  clearSelection() // 点击就清除掉框选的数据
  bulletinObj.value = subItem
  bulletinObj.value.isIndependence = 1
  bulletinObj.value.siteTypeName = item.siteTypeName
  drawerVisible.value = true
}

// 点击预约（默认 1 小时）
const handleClick = (item: any, t: any, rowIndex: number, cellIndex: number) => {
  // 阻止事件冒泡，避免与表格的mousedown事件冲突
  event?.stopPropagation()
  clearSelection() // 点击就清除掉框选的数据
  if (getMap(item.id, t).disabled && getMap(item.id, t).orderType == '') {
    return false
  }
  selectedCell.value = { rowIndex, cellIndex }
  const bulletinObjValue = getMap(item.id, t)
  bulletinObjValue.time = t.timeRange
  bulletinObjValue.bulletinDate = t.bulletinDate
  bulletinObjValue.detailVoList = getCell(item.id, t.time)?.detailVoList || []
  bulletinObj.value = bulletinObjValue
  drawerVisible.value = true
}

// 获取价格模版
const getTemplate = async () => {
  const { data } = await getTemplateList({
    stadiumId: props.stadiumId,
    siteType: siteParams.type,
  })
  templateList.value = data
}

// 应用价格模版
const changeTemplate = () => {
  if (tempSelect.value) {
    tempSelect.value.blur()
  }
  // 这里需要使用this.$modal.confirm，但在setup中需要其他方式
  const confirmed = confirm('是否确认应用此模版？')
  if (confirmed) {
    applyTemplateAction()
  } else {
    templateId.value = templateIdVal.value
  }
}

const applyTemplateAction = async () => {
  const tempParams = {
    templateId: templateId.value,
    stadiumId: props.stadiumId,
    dateTime: siteParams.date,
    siteType: siteParams.type,
  }
  if (tempSelect.value) {
    tempSelect.value.blur()
  }
  const res = await applyTemplate(tempParams)
  // 这里需要访问this.$message，但在setup中需要其他方式
  alert(res.msg) // 临时替代
  getBulletin()
  getReserve()
  getFit()
}

// 备份选择的模版id
const tempVisibleChange = (val: boolean) => {
  if (val) {
    templateIdVal.value = templateId.value
  }
}

// 查询暂存的场地类型列表
const getSiteType = async () => {
  const { data } = await selectSiteListBySiteType({
    stadiumId: props.stadiumId,
  })
  siteTypeList.value = data
}

// 设置价格
const handleSetSite = () => {
  showSetPrice.value = true
  const rowData = {
    children: siteData.value.siteList,
    stadiumId: props.stadiumId,
    type: siteParams.type,
    reserveList: siteData.value.reserveList,
  }
  nextTick(() => {
    if (sessionDetailRef.value) {
      sessionDetailRef.value.open(rowData)
    }
  })
}

// 去设置场地
const handleAddSite = () => {
  if (editSiteRef.value)
    if (siteTypeList.value.length == 0) {
      showAddType.value = true
      dataStatus.value = 'add'
    } else {
      showEditSite.value = true
      dataStatus.value = 'edit'
      editSiteRef.value.getDictTypeList()
    }
}

// 关闭查询订单和核销订单的popper
const closeVisible = () => {
  orderVisible.value = false
  writeOffVisible.value = false
}

// 关闭抽屉弹窗
const closeBulletin = () => {
  drawerVisible.value = false
  selectedCell.value = null
  bulletinObj.value = {}
  bulletinList.value = []
}

// 散客场地显示和隐藏
const changeShowFit = async (val: any, fit: any) => {
  try {
    const params = {
      id: fit.exhibitionId || '',
      siteId: fit.siteId,
      showFlag: val,
      userId: store.state.user.id,
    }
    const res = await updateShowSite(params)
    // 这里需要访问this.$message，但在setup中需要其他方式
    alert(res.msg) // 临时替代
  } catch (e) {
    fit.showFlag = fit.showFlag === '0' ? '1' : '0'
  }
}

// 在mounted时添加键盘事件监听
onMounted(() => {
  // 添加键盘事件监听，按esc清除选择
  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape') {
      clearSelection()
    }
  })
})

defineExpose({
  initData,
  resetData,
})
</script>

<style>
.table-wrapper {
  width: 100%;
  height: calc(100vh - 240px) !important;
  position: relative;
  border: 1px solid #e1e5e9;
  border-radius: 8px;
  overflow: hidden;
}
.table-container {
  height: 100%;
  position: relative;
  overflow: auto;
  width: 100%;
}

th {
  user-select: none;
  position: sticky;
}

td {
  transition: all 0.2s ease;
  user-select: none;
  cursor: default;
}

tr:nth-child(even) {
  background-color: #f9fafb;
}

tr:hover {
  background-color: #f1f5f9;
}

td.selected {
  background-color: rgba(75, 108, 183, 0.3);
  border-color: #4b6cb7;
  position: relative;
}

td.selected:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 2px solid #4b6cb7;
  pointer-events: none;
  background: rgba(59, 130, 246, 0.5);
}

.selection-box {
  position: absolute;
  background-color: rgba(75, 108, 183, 0.2);
  border: 2px solid #4b6cb7;
  pointer-events: none;
  z-index: 10;
  border-radius: 4px;
}

.controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
}

.selected-info {
  margin-left: 30px;
  font-weight: 500;
  color: #2c3e50;
  display: flex;
}

.selected-info span {
  font-weight: 600;
}
</style>

<style lang="scss" scoped>
.bulletin_box {
  .detail_item {
    background: #fff;
    padding: 15px;
  }
  .site_box {
    margin-top: 15px;
    // height: calc(100vh - 320px);
    // overflow: auto;
    .handle_site {
      display: flex;
      align-items: center;
      div {
        display: flex;
        align-items: center;
        font-size: 14px;
        color: #2a82e4;
        line-height: 21px;
        cursor: pointer;
        pointer-events: auto;
        &.edit {
          margin-left: 13px;
        }
        span {
          margin-left: 7px;
        }
      }
    }
    .site_cont {
      margin-top: 14px;
      .site_num {
        font-size: 14px;
        color: #383838;
      }
    }
    &.not_site {
      .handle_site div {
        pointer-events: none;
        color: #e5e5e5;
      }
      .site_num {
        color: #e5e5e5;
      }
    }
  }
  .date_box {
    .today {
      padding: 7px 5px 6px 4px;
      cursor: pointer;
      img {
        width: 14px;
        height: 15px;
      }
      span {
        display: block;
      }
    }
    .date_item {
      width: 49px;
      height: 48px;
      box-sizing: border-box;
      padding: 6px 0 0;
      background: #fff;
      margin-right: 12px;
      text-align: center;
      font-size: 12px;
      line-height: 18px;
      border-radius: 9px;
      cursor: pointer;
      color: #808080;
      position: relative;
      &.active {
        background: #0988fb;
        color: #fff;
      }
      &.today {
        background: #f1f2f3;
        color: #8c7d63;
      }
      span {
        font-size: 10px;
      }
      .today_logo {
        position: absolute;
        bottom: 2px;
        right: 2px;
        width: 8px;
        height: 8px;
      }
    }
    .date_sel {
      position: relative;
      :deep(.el-date-editor) {
        position: absolute; //绝对定位
        top: 0;
        left: 0;
        opacity: 0; //设置完全透明
        .el-input__inner {
          padding: 0;
          height: 48px;
          line-height: 48px;
        }
        .el-input__suffix {
          display: none;
        }
      }
    }
  }
  .search_boxs {
    p {
      font-size: 14px;
      line-height: 20px;
      color: #383838;
    }
    :deep(.el-input) {
      width: 200px;
      .el-input__inner {
        height: 29px;
        line-height: 29px;
      }
      .el-input__clear {
        line-height: 29px;
      }
    }
    .sure_btn {
      width: 56px;
      height: 29px;
      line-height: 29px;
      padding: 0;
      margin-left: 7px;
      border-radius: 6px;
      background: #2a82e4;
      color: #fff;
      border-color: #2a82e4;
    }
  }
  .motion_type {
    z-index: 99;
    display: flex;
    margin-left: 20px;
    .type_item {
      height: 28px;
      width: 68px;
      text-align: center;
      background: #e5e5e5;
      box-sizing: border-box;
      font-size: 14px;
      color: #383838;
      border-radius: 4px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 6px;
      cursor: pointer;
      margin-right: 5px;
      &.active {
        background: #2a82e4;
        color: #fff;
      }
    }
  }
  .select_table {
    height: calc(100vh - 240px) !important;
    overflow-x: auto;
    .table {
      display: block;
      width: 100%;
      position: relative;
      padding-right: 5px;
      table {
        border-collapse: collapse;
        border: none;
        width: 100%;
        thead {
          position: sticky;
          top: 0;
          background: #fff;
          z-index: 99;
          th,
          td {
            border: none;
            font-weight: 500;
            font-size: 14px;
          }
          .time {
            margin-left: -100%;
          }
          :deep(.el-select) {
            width: 110px;
            margin-right: 12px;
            .el-input__inner {
              height: 32px;
              line-height: 32px;
              &::placeholder {
                color: #808080;
              }
            }
            .el-select__caret {
              color: #808080;
            }
          }
          .reserve_num {
            height: 48px;
            p {
              width: 70px;
              height: 25px;
              line-height: 25px;
              border-radius: 33px;
              background: rgba(42, 130, 228, 0.26);
              color: #383838;
            }
          }
          tr:first-child {
            th:nth-child(2) {
              text-align: left;
              p {
                margin-left: 0;
              }
            }
          }
        }
        tbody {
          td {
            // width: 73px;
            height: 72px;
            text-align: center;
            font-size: 14px;
            border-color: #cfc4c4;
            cursor: pointer;
            padding: 0;
            .td_cell {
              height: 100%;
              display: flex;
              justify-content: center;
              align-items: center;
              .el-popover__reference {
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
              }
            }
            &.free {
              color: #2a82e4;
              &.selected {
                .td_cell {
                  border: 2px solid #00baad;
                  background: #c1f5d9;
                }
              }
            }
            &.expire {
              background: #e5e5e5;
              color: #fff;
              .text-custom-blue {
                color: #fff;
              }
            }
            &.booked {
              background: #2a82e4;
              color: #fff;
              text-align: left;
              vertical-align: top;
              .phone {
                font-size: 10px;
                line-height: 14px;
                margin-top: 13px;
                color: #fff;
              }
              &.selected {
                .td_cell {
                  border: 2px solid #d43030;
                }
              }
            }
            &.lock {
              background: #383838;
              &.selected {
                .td_cell {
                  border: 2px solid #00baad;
                }
              }
            }
            &.confirmed {
              background: #43cf7c;
              color: #fff;
              text-align: left;
              vertical-align: top;
              .phone {
                font-size: 10px;
                line-height: 14px;
                margin-top: 13px;
                color: #fff;
              }
              &.selected {
                .td_cell {
                  border: 2px solid #00baad;
                }
              }
            }
            &:first-child {
              border: none;
              padding-left: 38px;
            }
            .fit_item {
              background: #ff8d1a;
              border: 1px solid #cfc4c4;
              width: 51px;
              height: 72px;
              color: #fff;
              word-break: break-all;
              padding: 12px 7px 0 6px;
              text-align: left;
              border-right: 3px solid #bf6a13;
              box-sizing: border-box;
              &:first-child {
                margin-left: 4px;
              }
              &.active {
                border: 2px solid #00baad;
              }
              .nick_name {
                font-size: 10px;
              }
              .phone {
                font-size: 8px;
                margin-top: 6px;
                line-height: 12px;
              }
            }
          }
        }
      }
    }
  }
  .select_block {
    display: flex;
    align-items: center;
    margin-top: 27px;
    margin-left: 36px;
    .block_item {
      display: flex;
      align-items: center;
      margin-right: 12px;
      .block {
        width: 20px;
        height: 20px;
        box-sizing: border-box;
        margin-right: 6px;
      }
      p {
        font-size: 12px;
      }
      &:nth-child(1) {
        .block {
          border: 1px solid #2a82e4;
        }
      }
    }
  }
  .not_set {
    display: flex;
    justify-content: center;
    align-items: center;
    padding-top: 281px;
    img {
      width: 48px;
      height: 50px;
      margin-right: 18px;
    }
    .p1 {
      font-size: 16px;
      color: #a6a6a6;
      line-height: 24px;
    }
    .p2 {
      font-size: 16px;
      color: #0988fb;
      line-height: 24px;
      cursor: pointer;
    }
  }
}
:deep(.set_price_dialog) {
  padding-right: 0;
  .el-dialog__header {
    padding-top: 15px;
    padding-bottom: 30px;
  }
  .dialog_close {
    padding: 5px;
    cursor: pointer;
  }
  .el-dialog__body {
    padding: 0 20px;
    overflow: auto;
  }
}
</style>
